home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Mac Game Programming Gurus / TricksOfTheMacGameProgrammingGurus.iso / Book Chapters / 02 - Basic Game Graphics / Amalgam ƒ / Amalgam.c next >
Encoding:
C/C++ Source or Header  |  1995-03-30  |  9.7 KB  |  395 lines  |  [TEXT/MMCC]

  1. //\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/
  2. //
  3. //    Amalgam.c
  4. //
  5. //    The application uses a modeless dialog to present user with several buttons, 
  6. //    each of which performs an interesting action:
  7. //
  8. //    o    finds deepest screen available; since there may be more than
  9. //        one, this simply returns the last deepest one in the GDevice list.
  10. //    o    finds the screen with the largest area; again, since there may
  11. //        be more than one in the list with similar resolutions, this will
  12. //        return the last, largest one it found in the GDevice list.
  13. //    o    allows you to take over an entire window; if you have more than
  14. //        one screen available, whichever one contains a larger portion of
  15. //        the dialog will be taken over.
  16. //    o    hide and un-hide the menubar.
  17. //    o    demonstrates fading a GDevice to black and back again.
  18. //    o    More intelligent window zooming; windows are zoomed out to whichever
  19. //        screen the majority of their real estate is on; access of this function
  20. //        is via the usual zoom-box; since we do not provide for window re-sizing,
  21. //        you may re-set the size of the window by option-clicking the zoom box.
  22. //
  23. //    Notes:
  24. //
  25. //    +    clicking in the close box of the dialog quits the program
  26. //    +    though the program lets you hide the menubar at any time, real programs
  27. //        would only do so if they were taking over the entire main screen; to see
  28. //        what this is like, Minimax the dialog so it fills the main screen, then
  29. //        hide the menubar--now, click where the menubar was and it will reappear,
  30. //        then, click elsewhere in the dialog and it will resume hiding--this is
  31. //        what real games do.
  32. //    +    fading demonstrated here fades an entire screen. This is the most robust
  33. //        method of fading as it avoids some problems presented by the 68KAV Macs;
  34. //        other methods of fading are to slowly modify the device's gamma, and 
  35. //        doing a Color Table animation fade, but both of these methods may fail
  36. //        on the AVs.
  37. //    
  38. //    History:
  39. //
  40. //    950305 jb: Written
  41. //
  42. //\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/
  43.  
  44.  
  45. //  __#Defines________________________________________________________________________
  46. #define kAmalgamDLOGID            128
  47.  
  48. #define kSleepTix                10        //defines how much time we give up if there aren't
  49.                                         //any events for our app
  50.  
  51. //  __#Headers________________________________________________________________________
  52. #include "QDOffscreen.h"
  53. #include "Menu.h"
  54. #include "Amalgam.h"
  55. #include "OurDlog.h"
  56.  
  57. //  __#Protos_________________________________________________________________________
  58. //  __ Macros_________________________________________________________________________
  59. //  __ Enums__________________________________________________________________________
  60. //  __ Typedefs_______________________________________________________________________
  61. //  __ Static Protos__________________________________________________________________
  62. static Boolean OpenOurModelessDialog( void );
  63. static Boolean InitApp( void );
  64. static void QuitApp( void );
  65.  
  66. static void EventLoop( void );
  67. static void HandleEvent( void );
  68.  
  69. //  __ Extern Globals_________________________________________________________________
  70. OSErr                gErr;
  71. Str32                gAppName;
  72. DialogPtr            gMainDlogPtr;
  73. CGrafPtr            gMainDlogPort;
  74. GDHandle            gMainDlogGDev;
  75. EventRecord            gTheEvent;
  76. Boolean                gInForeground;
  77. Boolean                gQuitting;
  78.  
  79. GDHandle            gMainDevice;
  80. short                gNumActiveScreens;
  81. Rect                gOriginalDlogPortRect;
  82.  
  83. //  __ Static Globals_________________________________________________________________
  84. //  __ Functions______________________________________________________________________
  85.  
  86.  
  87. //____ main __________________________________________________________________________
  88. //
  89. void main( void )
  90. {
  91.     if (InitApp())        //Initialize managers, allocate global structures, etc…
  92.     {
  93.         EventLoop();    //Handle events until user quits
  94.         
  95.         QuitApp();        //dispose and release everything
  96.     }
  97.     
  98. }//main
  99.  
  100.  
  101. //____ InitApp __________________________________________________________________________
  102. //
  103. //    Returns FALSE if there were any problems initializing, or if the System lacks
  104. //    any amenities we require.
  105. //
  106. static Boolean InitApp( void )
  107. {
  108.     ToolBoxInit();
  109.     
  110.     if (!EnviroCheck())
  111.         return FALSE;
  112.         
  113.     gInForeground = TRUE;
  114.  
  115.     InitOurMenubar();
  116.  
  117.     StartupHideMenuBar();            //initialize stuff for hiding menu bar
  118.     
  119.     gMainDevice = GetMainDevice();
  120.     gNumActiveScreens = CountAvailableDevices();
  121.     
  122.     GetAppName((char *)gAppName);
  123.  
  124.     if (!OpenOurModelessDialog())
  125.         return FALSE;
  126.     
  127.     gQuitting = FALSE;
  128.  
  129.     
  130.     return TRUE;
  131. }//InitApp
  132.  
  133.  
  134. //____ QuitApp __________________________________________________________________________
  135. //
  136. //    Dispose of and release anything and everything
  137. //
  138. static void QuitApp( void )
  139. {
  140.     if (NULL != gMainDlogPtr)
  141.         DisposeDialog(gMainDlogPtr);
  142.     
  143.     ShutdownHideMenuBar();
  144.     
  145. }//QuitApp
  146.  
  147.  
  148. //____ OpenOurModelessDialog __________________________________________________________________________
  149. //
  150. //    Open our window, install palette built from a resource CTable.
  151. //    provided by the System.
  152. //
  153. static Boolean OpenOurModelessDialog( void )
  154. {
  155. Rect        mainScreenRect;
  156.  
  157.     // create and show the window
  158.     gMainDlogPtr = GetNewDialog( kAmalgamDLOGID, NULL, (WindowRef)-1);
  159.     if (NULL == gMainDlogPtr)
  160.         return FALSE;
  161.  
  162.     mainScreenRect = (**gMainDevice).gdRect;
  163.     mainScreenRect.top += LMGetMBarHeight();
  164.     CenterWindowInRect(gMainDlogPtr, &mainScreenRect, TRUE);
  165.  
  166.     ShowWindow( gMainDlogPtr );
  167.     SetPort( gMainDlogPtr );
  168.  
  169.     gOriginalDlogPortRect = gMainDlogPtr->portRect;
  170.     
  171.     GetGWorld( &gMainDlogPort, &gMainDlogGDev );    //save this info for later convenience
  172.         
  173.     return TRUE;
  174. }//OpenOurModelessDialog
  175.  
  176.  
  177. //____ EventLoop __________________________________________________________________________
  178. //
  179. //    Nifty function shows off some ways to do Palette Animation
  180. //
  181. //    Returns    void
  182. //
  183. static void EventLoop( void )
  184. {
  185. Boolean            done;
  186.     
  187.     done = FALSE;
  188.     while (!done)
  189.     {
  190.         WaitNextEvent(everyEvent, &gTheEvent, kSleepTix, 0L);
  191.         
  192.         HandleEvent();
  193.         
  194.         if (gQuitting)
  195.         {
  196.             done = TRUE;
  197.         }
  198.  
  199.  
  200.     }//while
  201.  
  202. }//EventLoop
  203.  
  204.  
  205.  
  206.  
  207. //____ HandleEvent __________________________________________________________________________
  208. //
  209. //    Handles a single event
  210. //
  211. //    Returns    void
  212. //
  213. static void HandleEvent( void )
  214. {
  215. #define    kSuspendingOrResuming    0x0001
  216. #define    kResuming                1
  217.  
  218.     //intercept events for the modeless dialog here
  219.     if (IsDialogEvent(&gTheEvent))
  220.     {
  221.         if (HandleOurDlogEvent())
  222.             return;
  223.     }
  224.         
  225.     //okay, normal event happend. Ho hum.
  226.     switch (gTheEvent.what)
  227.     {
  228.         case nullEvent:
  229.         break;
  230.  
  231.         case mouseDown:
  232.             HandleMouseDown();
  233.         break;//mouseDown
  234.         
  235.         case keyDown:
  236.         case autoKey:
  237.             HandleKey();
  238.         break;
  239.         
  240.         case updateEvt:
  241.         break;
  242.  
  243.                 
  244.         case    osEvt:
  245.             switch ((gTheEvent.message & osEvtMessageMask) >> 24)
  246.             {
  247.                 case    mouseMovedMessage:
  248.                 break;
  249.                     
  250.                 case    suspendResumeMessage:                    
  251.                     if (gTheEvent.message & resumeFlag)
  252.                     {
  253.                         gInForeground = TRUE;
  254.                         
  255.                     }
  256.                     else
  257.                     {
  258.                         gInForeground = FALSE;
  259.                     }
  260.         
  261.                     CheckMenuHide(NULL);
  262.  
  263.                     if (gTheEvent.message & convertClipboardFlag)
  264.                         ;
  265.  
  266.                 break;    //suspendResumeMessage
  267.             }//switch gTheEvent.message & osEvtMessageMask
  268.         break;//osEvt
  269.  
  270.         case    diskEvt:
  271.             //    This handles a bad disk.  Otherwise the disk will not eject.
  272.             if ( gTheEvent.message >> 16 )
  273.             {
  274.                 Point    tempPoint;
  275.                 tempPoint.v = 50; tempPoint.h = 50;
  276.                 DIBadMount(tempPoint, gTheEvent.message);
  277.             }
  278.         break;
  279.  
  280.     }//switch (gTheEvent.what)
  281.  
  282. }//HandleEvent
  283.  
  284.  
  285.  
  286.  
  287. //____ HandleKey __________________________________________________________________________
  288. //
  289. //    Handles a keystroke; looks in gTheEvent to find it
  290. //
  291. //    Returns    void
  292. //
  293. void HandleKey( void )
  294. {
  295. char            theChar;
  296.  
  297.     theChar = gTheEvent.message & charCodeMask;
  298.     if ((gTheEvent.modifiers & cmdKey) != 0)
  299.     {
  300.         HandleMenuChoice(MenuKey(theChar));
  301.         return;
  302.     }
  303.     
  304.     //keystroke wasn't a cmd-key combo; could test for
  305.     //regular keys here...
  306.     
  307.     CheckMenuHide(NULL);
  308.  
  309.     return;    
  310. }//HandleKey
  311.  
  312.  
  313. //____ HandleMouseDown __________________________________________________________________________
  314. //
  315. //    Normally called from the event loop, this expects mousedown info to be
  316. //    in the gTheEvent global.
  317. //
  318. void HandleMouseDown( void )
  319. {
  320. WindowPtr        whichWindow;
  321. short int        thePart;
  322. long            menuChoice;
  323. Rect            windowStructRect;
  324.  
  325. RgnHandle        theGrayRgn;
  326. Rect            grayRgnLimitRect;
  327.  
  328.     //if click would be in menubar, show the menubar if hidden
  329.     CheckMenuHide(&gTheEvent.where);
  330.  
  331.     thePart = FindWindow(gTheEvent.where, &whichWindow);
  332.     
  333.     //did user click anywhere in a window? If so, if it's not front window, bring it
  334.     //to the fore
  335.     if (NULL != whichWindow)
  336.     {
  337.         windowStructRect = mWindStructRect(whichWindow);
  338.         if ((PtInRect(gTheEvent.where, &windowStructRect)) && (whichWindow != FrontWindow()))
  339.             SelectWindow(whichWindow);
  340.     }
  341.     
  342.     switch(thePart)
  343.     {
  344.         case inMenuBar:
  345.             menuChoice = MenuSelect(gTheEvent.where);
  346.             HandleMenuChoice(menuChoice);
  347.         break;
  348.  
  349.         case inSysWindow:
  350.             SystemClick(&gTheEvent, whichWindow);
  351.         break;
  352.  
  353.         case inContent:
  354.         break;
  355.  
  356.         case inDrag:
  357.             //was click in titleBar of our app? Let's drag it around, shall we?
  358.             if (whichWindow == gMainDlogPtr)
  359.             {
  360.                 theGrayRgn = GetGrayRgn();        //get region of all active screens
  361.                                                 //region changes when screens are moved
  362.                                                 //or the menu bar is hidden/unhidden
  363.                 grayRgnLimitRect = (**theGrayRgn).rgnBBox;
  364.                 if (inDrag == thePart)
  365.                 {
  366.                     DragWindow( gMainDlogPtr, gTheEvent.where, &grayRgnLimitRect);
  367.                 }
  368.             }
  369.             
  370.         break;
  371.             
  372.         case inGrow:
  373.         break;
  374.         
  375.         case inZoomIn:        //use wants to shrink window
  376.         case inZoomOut:        //user wants to grow window
  377.             if ((whichWindow == gMainDlogPtr) && 
  378.                 (TrackBox( whichWindow, gTheEvent.where, thePart )))
  379.                     ZoomOurDialog( thePart );
  380.         break;
  381.         
  382.         case inGoAway:
  383.             if ((whichWindow == gMainDlogPtr) && 
  384.                 (TrackGoAway(whichWindow, gTheEvent.where)))
  385.             {
  386.                 gQuitting = TRUE;
  387.             }
  388.  
  389.         break;
  390.     }        
  391.  
  392.     CheckMenuHide(NULL);
  393.  
  394. }//HandleMouseDown
  395.